package com.wxy.favorites.controller;

import cn.hutool.http.ContentType;
import com.wxy.favorites.config.AppConfig;
import com.wxy.favorites.dto.DownloadFileDto;
import com.wxy.favorites.dto.FilePageDto;
import com.wxy.favorites.dto.UserCapacityDto;
import com.wxy.favorites.entity.UserFile;
import com.wxy.favorites.security.ContextUtils;
import com.wxy.favorites.security.SecurityUser;
import com.wxy.favorites.service.UserFileService;
import com.wxy.favorites.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@RestController
@RequestMapping("/file")
@Slf4j
@Api(tags = "文件")
@Secured("file")
public class FileController {

    @Autowired
    private UserFileService userFileService;

    @Autowired
    private UserService userService;

    @Autowired
    private AppConfig appConfig;

    @GetMapping("/rootCount")
    @ApiOperation(value = "查询文件总数")
    public UserCapacityDto rootCount() {
        return userFileService.rootCount();
    }

    @GetMapping("/exists/{id}")
    @ApiOperation(value = "判断文件是否存在")
    public Boolean exists(@PathVariable Integer id) {
        return userFileService.existFile(id);
    }

    @GetMapping("/share/{id}")
    @ApiOperation(value = "分享文件")
    public String share(@PathVariable Integer id) {
        return userFileService.share(id);
    }

    /**
     * 获取文件列表
     *
     * @param name 文件名称
     * @param pid  父文件夹
     * @return
     */
    @GetMapping("/list")
    @ApiOperation(value = "获取文件列表")
    public FilePageDto list(@RequestParam(required = false) String name,
                            @RequestParam(required = false) Integer pid,
                            @RequestParam(required = false) Integer pageNum,
                            @RequestParam(required = false) Integer pageSize) {
        return userFileService.findPage(name, pid, pageNum, pageSize);
    }

    @PostMapping("/rename")
    @ApiOperation(value = "重命名")
    public Boolean rename(@RequestParam Integer id, @RequestParam String filename) {
        return userFileService.rename(id, filename);
    }

    @GetMapping("/share/cancel/{id}")
    @ApiOperation(value = "取消分享")
    public void shareCancel(@PathVariable Integer id) {
        userService.shareCancel(id);
    }

    @GetMapping("/download/{id}")
    @ApiOperation(value = "下载文件")
    public void download(HttpServletResponse response, @PathVariable Integer id) throws IOException {
        DownloadFileDto dto = userFileService.getFile(id);
        response.setContentType(ContentType.OCTET_STREAM.getValue());
        response.addHeader("Content-Disposition", "attachment;fileName=" + new String(dto.getFilename().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
        try (ServletOutputStream out = response.getOutputStream()) {
            Files.copy(dto.getPath(), out);
        }
    }

    @GetMapping("/downloadAll")
    @ApiOperation(value = "备份")
    public void downloadAll(HttpServletResponse response) throws IOException {
        userFileService.downloadAll(response.getOutputStream());
    }

    @PostMapping("/upload")
    @ApiOperation(value = "批量上传")
    public void upload(@RequestParam("file") MultipartFile[] files, @RequestParam(required = false) Integer pid) throws IOException {
        userFileService.upload(files, pid);
    }

    @GetMapping("/back")
    @ApiOperation(value = "返回上一级")
    public Integer goBack(@RequestParam(required = false) Integer pid) {
        return Optional.ofNullable(userFileService.findById(pid)).map(UserFile::getPid).orElse(null);
    }

    @PostMapping("/delete")
    @ApiOperation(value = "删除文件")
    public void delete(@RequestParam Integer id) throws IOException {
        SecurityUser user = ContextUtils.getCurrentUser();
        userFileService.deleteById(id, user.getId());
    }

    @PostMapping("/deleteMore")
    @ApiOperation(value = "批量删除")
    public void deleteMore(@RequestParam String ids) throws IOException {
        userFileService.deleteMore(ids);
    }

    @PostMapping("/folder")
    @ApiOperation(value = "新建文件夹")
    public void newFolder(@RequestParam String filename, @RequestParam(required = false) Integer pid) {
        userFileService.newFolder(filename, pid);
    }

    /**
     * 移动文件
     *
     * @return
     */
    @PostMapping("/move")
    @ApiOperation(value = "移动文件")
    public void move(@RequestParam String ids, @RequestParam(required = false) Integer pid) {
        userFileService.move(ids, pid);
    }


    @GetMapping("/view")
    @ApiOperation(value = "预览")
    public String view(@RequestParam Integer id) {
        return userFileService.viewAsText(id);
    }

    @GetMapping("/tree")
    @ApiOperation(value = "获取文件夹树")
    public List<Map<String, Object>> tree() {
        return userFileService.getTree();
    }

    @GetMapping("/capacity")
    @ApiOperation(value = "查询用户使用容量")
    public UserCapacityDto capacity() {
        return userService.findCapacity();
    }
}
